package com.xuecheng.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.OrdersConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.CoursePubIndexVo;
import com.xuecheng.commons.model.vo.OrdersVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.learning.api.LearningClient;
import com.xuecheng.order.domain.Orders;
import com.xuecheng.order.domain.Payment;
import com.xuecheng.order.mappers.OrdersMapper;
import com.xuecheng.order.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.order.service.PaymentService;
import com.xuecheng.order.utils.PayUtils;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exceptions.BusinessException;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 订单 服务实现类
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
    @Autowired
    private SearchClient searchClient;
    //创建订单
    @Override
    public ResponseResult<String> create(Long coursePubId) {
        //1.查询当前用户是否有已支付的订单
        LambdaQueryWrapper<Orders> wq = new LambdaQueryWrapper<>();
        wq.eq(Orders::getUserId, AuthInfoHolder.getUserId());//当前用户
        wq.eq(Orders::getCoursePubId,coursePubId);//本课程
        wq.eq(Orders::getStatus, OrdersConstants.ORDER_PAID_STATUS);//已支付状态
        Orders one = getOne(wq);
        if (one != null) {
            throw new BusinessException(ErrorCode.PAYERROR);
        }
        //2.查询当前用户是否有已创建未支付的订单
        LambdaQueryWrapper<Orders> wq1 = new LambdaQueryWrapper<>();
        wq1.eq(Orders::getUserId, AuthInfoHolder.getUserId());//当前用户
        wq1.eq(Orders::getCoursePubId,coursePubId);//本课程
        wq1.eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS);//已创建状态
        Orders one1 = getOne(wq1);
        if (one1 != null) {
            throw new BusinessException(ErrorCode.PAYERROR);
        }
        //3.调用feign接口查询当前课程的发布数据
        ResponseResult<CoursePubIndexVo> result = searchClient.findById(coursePubId);
        CoursePubIndexVo vo = result.getData();
        //4.构造订单对象，设置属性
        Orders orders = new Orders();
        orders.setOrderNo(UUID.randomUUID().toString(true));
        orders.setCoursePubId(coursePubId);
        orders.setCoursePubName(vo.getName());
        orders.setCompanyId(vo.getCompanyId());
        orders.setUserId(AuthInfoHolder.getUserId());
        orders.setPrice(1L);//单位是分，1分钱
        orders.setStatus(OrdersConstants.ORDER_INIT_STATUS);//已创建状态
        orders.setCreateDate(new Date());
        //5.保存到数据库
        boolean save = save(orders);
        if (!save) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        return ResponseResult.okResult(orders.getOrderNo());
    }

    @Autowired
    private PayUtils payUtils;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private LearningClient learningClient;

    //查询支付结果
    @Override
    @GlobalTransactional
    public ResponseResult<OrdersVo> queryOrders(String orderNo) {
        //1.查询订单
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(Orders::getOrderNo,orderNo);
        Orders orders = getOne(qw);
        //2.订单不存在就抛异常
        if (orders == null) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        //3.订单存在且为未支付状态
        if (orders.getStatus().equals(OrdersConstants.ORDER_INIT_STATUS)) {
            //4.查询微信支付状态，如果成功
            Boolean payment = payUtils.checkPayment(orderNo);
            if (payment) {
                //4.1更新订单状态
                orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
                updateById(orders);
                //4.2更新支付状态
                LambdaQueryWrapper<Payment> qw1 = new LambdaQueryWrapper<>();
                qw1.eq(Payment::getOrderNo,orderNo);
                Payment one = paymentService.getOne(qw1);
                one.setStatus(OrdersConstants.ORDER_PAID_STATUS.toString());
                paymentService.updateById(one);
                //5.调用feign接口保存或者更新选课记录
                RecordDto dto = new RecordDto();
                dto.setCoursePubId(orders.getCoursePubId());
                dto.setUserId(orders.getUserId());
                learningClient.saveRecord(dto);
            }
        }
        OrdersVo vo = BeanHelper.copyProperties(orders, OrdersVo.class);
        return ResponseResult.okResult(vo);
    }
    //清理超时订单
    @Override
    public void getPayment() {
        //1.查询15分钟之前的订单
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        String time = DateUtil.offsetMinute(new Date(), 15).toString();//获取15分钟前的时间
        qw.lt(Orders::getCreateDate,time);
        qw.eq(Orders::getStatus,OrdersConstants.ORDER_INIT_STATUS);
        List<Orders> list = list(qw);
        log.info("超时订单共有:"+list);
        if (list == null || list.size() == 0) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        //2.列表循环，查询微信支付状态
        for (Orders orders : list) {
            log.info("处理超时订单：{}"+orders.getOrderNo());
            Boolean payment = payUtils.checkPayment(orders.getOrderNo());
            //3.如果已经支付
            if (payment) {
                //3.1更新订单状态
                orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
                updateById(orders);
                //3.2更新支付状态
                LambdaQueryWrapper<Payment> qw1 = new LambdaQueryWrapper<>();
                qw1.eq(Payment::getOrderNo, orders.getOrderNo());
                Payment one = paymentService.getOne(qw1);
                one.setStatus(OrdersConstants.ORDER_PAID_STATUS.toString());
                paymentService.updateById(one);
                //3.3.调用feign接口保存或者更新选课记录
                RecordDto dto = new RecordDto();
                dto.setCoursePubId(orders.getCoursePubId());
                dto.setUserId(orders.getUserId());
                learningClient.saveRecord(dto);
            } else {
                //4.否则，修改订单状态为关闭，通知微信关闭支付
                orders.setStatus(OrdersConstants.ORDER_CLOSED_STATUS);
                updateById(orders);
                payUtils.closeOrder(orders.getOrderNo());
            }
        }
    }
}
